using System;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Web;
using System.Text;
using System.Text.RegularExpressions;

namespace AliCMS.SystemModule.Bll
{
    public partial class Module : ObjectBase, IModule
    {
        public class Dictionary : XmlObjectBase, SystemModule.Module.IDictionary
        {
			public Dictionary(int instanceID, string lang, bool checkRight, string database)
				: base(instanceID, lang, checkRight)
			{
			}

			public override object ExecuteService(HttpContext context)
			{
                object result = null;

                string operation = context.Request.QueryString["Operation"];
                if (operation == "Add")
                {
                    string ns = context.Request.QueryString["Namespace"];

                    Dictionary<string, object> item = new Dictionary<string, object>();
                    string value = null;
                    item[Alias.Module.Dictionary.Name] = context.Request.Form["Name"];
                    value = context.Request.Form["Content"];
                    if (value != null) item[Alias.Module.Dictionary.Content] = value;

                    Add(ns, item);
                }
                else if (operation == "Modify")
                {
                    string ns = context.Request.QueryString["Namespace"];
                    string name = context.Request.QueryString["Name"];

                    Dictionary<string, object> changes = new Dictionary<string, object>();
                    string value = null;
                    value = context.Request.Form["Name"];
                    if (value != null) changes[Alias.Module.Dictionary.Name] = value;
                    value = context.Request.Form["Content"];
                    if (value != null) changes[Alias.Module.Dictionary.Content] = value;

                    Modify(ns, name, changes);
                }
                else if (operation == "Delete")
                {
                    string ns = context.Request.QueryString["Namespace"];
                    string name = context.Request.QueryString["Name"];

                    Delete(ns, name);
                }
                else if (operation == "List")
                {
                    result = HandleCommonList(context);
                }
                else
                {
                    throw new Exception("lang_header_param");
                }

                return result;
            }

			public Dictionary<string, object> Get(string ns, string name)
            {
                if (CheckRight)
                {
                    ValidateRight("Get", Guid.Empty);
                }

                string path = Manager.MapPath(Manager.GetModulePath(ns) + "dictionary/" + Lang + ".config");
                if (!File.Exists(path))
                    return null;

                XmlDoc.Load(path);

                XmlNode node = XmlDoc.SelectSingleNode("//Item[@Name='" + name + "']");
                if (node == null)
                    return null;

                Dictionary<string, object> result = new Dictionary<string, object>();

                result[Alias.Module.Dictionary.Name] = name;
                result[Alias.Module.Dictionary.Content] = node.InnerText;

                return result;
            }
			public void Add(string ns, Dictionary<string, object> item)
            {
                if (CheckRight)
                {
                    ValidateRight("Add", Guid.Empty);
                }

                string path = Manager.MapPath(Manager.GetModulePath(ns) + "dictionary/");
                Manager.MakeSureFolderExist(path);
                path = Path.Combine(path, Lang + ".config");
                if (File.Exists(path))
                    XmlDoc.Load(path);
                else
                    XmlDoc.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?><configuration></configuration>");

                if (item.ContainsKey(Alias.Module.Dictionary.Name))
                {
                    XmlNode node = XmlDoc.SelectSingleNode("//Item[@Name='" + item[Alias.Module.Dictionary.Name] + "']");
                    if (node != null)
                        throw new Exception("lang_dictionary_item_name_exist");
                }

                XmlNode itemNode = XmlDoc.CreateElement("Item");

                XmlAttribute name = XmlDoc.CreateAttribute("Name");
                name.Value = item[Alias.Module.Dictionary.Name].ToString();
                itemNode.Attributes.Append(name);

                if (item.ContainsKey(Alias.Module.Dictionary.Content))
                    itemNode.InnerText = item[Alias.Module.Dictionary.Content].ToString();

                XmlDoc.DocumentElement.AppendChild(itemNode);
                XmlDoc.Save(path);
            }
			public void Modify(string ns, string name, Dictionary<string, object> changes)
            {
                if (CheckRight)
                {
                    ValidateRight("Modify", Guid.Empty);
                }

                string path = Manager.MapPath(Manager.GetModulePath(ns) + "dictionary/" + Lang + ".config");
                if (!File.Exists(path))
                    return;

                XmlDoc.Load(path);

                XmlNode itemNode = XmlDoc.SelectSingleNode("//Item[@Name='" + name + "']");
                if (itemNode == null)
                    return;

                if (changes.ContainsKey(Alias.Module.Dictionary.Name) && name != changes[Alias.Module.Dictionary.Name].ToString())
                {
                    XmlNode node = XmlDoc.SelectSingleNode("//Item[@Name='" + changes[Alias.Module.Dictionary.Name] + "']");
                    if (node != null)
                        throw new Exception("lang_dictionary_item_name_exist");

                    XmlAttribute nameNode = itemNode.Attributes["Name"];
                    if (nameNode == null)
                    {
                        nameNode = XmlDoc.CreateAttribute("Name");
                        itemNode.Attributes.Append(nameNode);
                    }
                    nameNode.Value = changes[Alias.Module.Dictionary.Name].ToString();
                }

                if (changes.ContainsKey(Alias.Module.Dictionary.Content))
                    itemNode.InnerText = changes[Alias.Module.Dictionary.Content].ToString();

                XmlDoc.Save(path);
            }
			public void Delete(string ns, string name)
            {
                if (CheckRight)
                {
                    ValidateRight("Delete", Guid.Empty);
                }

                string path = Manager.MapPath(Manager.GetModulePath(ns) + "dictionary/" + Lang + ".config");
                if (!File.Exists(path))
                    throw new Exception("lang_dictionary_config_file_not_exist");

                XmlDoc.Load(path);

                Dictionary<string, object> item = new Dictionary<string, object>();
                XmlNode node = XmlDoc.SelectSingleNode("//Item[@Name='" + name + "']");
                if (node == null)
                    return;
                XmlDoc.DocumentElement.RemoveChild(node);

                XmlDoc.Save(path);
            }
			public DataTable List(int page, int pageSize, Dictionary<string, object> condition, Dictionary<string, string> sort)
			{
				return _List(page, pageSize, condition, sort);
			}
			protected override DataTable _List(int page, int pageSize, Dictionary<string, object> condition, Dictionary<string, string> sort)
            {
                if (CheckRight)
                {
                    ValidateRight("List", Guid.Empty);
                }

                DataTable result = new DataTable();
                result.Columns.Add(Alias.Module.Dictionary.Name, typeof(string));
                result.Columns.Add(Alias.Module.Dictionary.Content, typeof(string));

                if (condition == null || !condition.ContainsKey(Alias.Module.Dictionary.Namespace))
                    return result;

                string path = Manager.MapPath(Manager.GetModulePath(condition[Alias.Module.Dictionary.Namespace].ToString()) + "dictionary/" + Lang + ".config");
                if (!File.Exists(path))
                    return result;

                XmlDoc.Load(path);

                int curIndex = 0, rowIndex = 0;
                int startIndex = (page - 1) * pageSize;

                XmlNodeList nodes = null;
                if (condition.Count > 1)
                {
                    string xpath = null;
                    if (condition.ContainsKey(Alias.Module.Dictionary.Name))
                    {
                        xpath = "//Item[contains(@Name,'" + condition[Alias.Module.Dictionary.Name] + "')]";
                    }

                    if (condition.ContainsKey(Alias.Module.Dictionary.Content))
                    {
                        if (xpath != null)
                            xpath += " and ";

                        xpath += "//Item[contains(.,'" + condition[Alias.Module.Dictionary.Content] + "')]";
                    }

                    nodes = XmlDoc.SelectNodes(xpath);
                }
                else
                {
                    nodes = XmlDoc.DocumentElement.ChildNodes;
                }
                for (int i = 0; i < nodes.Count; i++)
                {
                    if (pageSize != -1)
                    {
                        if (curIndex < startIndex)
                        {
                            curIndex++;
                            continue;
                        }

                        if (rowIndex == pageSize)
                            break;
                    }

                    XmlNode itemNode = nodes[i];

                    DataRow newRow = result.NewRow();
                    if (itemNode.Attributes["Name"] != null)
                        newRow[Alias.Module.Dictionary.Name] = itemNode.Attributes["Name"].Value;
                    else
                        newRow[Alias.Module.Dictionary.Name] = String.Empty;
                    newRow[Alias.Module.Dictionary.Content] = itemNode.InnerText;
                    result.Rows.Add(newRow);

                    rowIndex++;
                }

                return result;
            }
			public DataTable List(int page, int pageSize, string condition, string sort)
            {
                Dictionary<string, object> newCondition = null;
                if (!String.IsNullOrEmpty(condition))
                {
                    newCondition = new Dictionary<string, object>();
                    string[] conditions = condition.Split(new string[] { " and ", " AND " }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string c in conditions)
                    {
                        string[] pair = c.Split('=');
                        if (pair[0] == Alias.Module.Dictionary.Name)
                            newCondition[Alias.Module.Dictionary.Name] = pair[1].Trim('\'');
                        else if (pair[0] == Alias.Module.Dictionary.Content)
                            newCondition[Alias.Module.Dictionary.Content] = pair[1].Trim('\'');
                        else if (pair[0] == Alias.Module.Dictionary.Namespace)
                            newCondition[Alias.Module.Dictionary.Namespace] = pair[1].Trim('\'');
                        else
                            newCondition[pair[0]] = pair[1];
                    }
                }

                return List(page, pageSize, newCondition, null);
            }
			public int GetRecordCount(Dictionary<string, object> condition)
            {
                DataTable result = _List(-1, -1, condition, null);
                return result.Rows.Count;
            }
			public int GetRecordCount(string condition)
            {
                Dictionary<string, object> newCondition = null;
                if (!String.IsNullOrEmpty(condition))
                {
                    newCondition = new Dictionary<string, object>();
                    string[] conditions = condition.Split(new string[] { " and ", " AND " }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string c in conditions)
                    {
                        string[] pair = c.Split('=');
                        if (pair[0] == Alias.Module.Dictionary.Name)
                            newCondition[Alias.Module.Dictionary.Name] = pair[1].Trim('\'');
                        else if (pair[0] == Alias.Module.Dictionary.Content)
                            newCondition[Alias.Module.Dictionary.Content] = pair[1].Trim('\'');
                        else if (pair[0] == Alias.Module.Dictionary.Namespace)
                            newCondition[Alias.Module.Dictionary.Namespace] = pair[1].Trim('\'');
                        else
                            newCondition[pair[0]] = pair[1];
                    }
                }

                return GetRecordCount(newCondition);
            }
        }
    }
}
